package cl.mt.data;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Collection;
import java.util.LinkedList;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;

import cl.mt.dto.DTOOfertaCarga;
import cl.mt.dto.filtros.FiltroCargaDTO;
import cl.mt.mvc.action.transportista.helper.FiltroTransportistaDTO;
import cl.mt.util.bd.DatosTabla;
import cl.mt.util.bd.Parametro;

public class DataOfertaCarga extends DatosTabla {

	private Logger log = LogManager.getLogger(DataOfertaCarga.class.getName());

	private static final String sqlGetId = "SELECT MAX(ID)+1 AS IDX FROM MASTRANSPORTE.MST_OFERTAS_CARGA";
	private static final String sqlFindByPK = "SELECT ID, USR_ID, PLT_ID, RMT_ID, CAT_ID, CIU_ORG_ID, CIU_DST_ID, VHT_ID, UNI_ID, FECHA_DESDE, FECHA_HASTA, FECHA_PUBLICACION, DETALLE_CARGA, ELIMINADO, NUMERO_VIAJES, PRECIO_REFERENCIAL, ESPECIFICACION_ENTREGA, MOT_ID, CANTIDAD, MERCADERIA, FECHA_CADUCIDAD FROM MASTRANSPORTE.MST_OFERTAS_CARGA where ID=?";
	private static final String sqlFindAll = "SELECT ID, USR_ID, PLT_ID, RMT_ID, CAT_ID, CIU_ORG_ID, CIU_DST_ID, VHT_ID, UNI_ID, FECHA_DESDE, FECHA_HASTA, FECHA_PUBLICACION, DETALLE_CARGA, ELIMINADO, NUMERO_VIAJES, PRECIO_REFERENCIAL, ESPECIFICACION_ENTREGA, MOT_ID, CANTIDAD, MERCADERIA, FECHA_CADUCIDAD FROM MASTRANSPORTE.MST_OFERTAS_CARGA where  ELIMINADO='N' and fecha_caducidad>=current_date";
	private static final String sqlFindSinWhere = "SELECT ID, USR_ID, PLT_ID, RMT_ID, CAT_ID, CIU_ORG_ID, CIU_DST_ID, VHT_ID, UNI_ID, FECHA_DESDE, FECHA_HASTA, FECHA_PUBLICACION, DETALLE_CARGA, ELIMINADO, NUMERO_VIAJES, PRECIO_REFERENCIAL, ESPECIFICACION_ENTREGA, MOT_ID, CANTIDAD, MERCADERIA, FECHA_CADUCIDAD FROM MASTRANSPORTE.MST_OFERTAS_CARGA";
	private static final String sqlCreate = "INSERT INTO MASTRANSPORTE.MST_OFERTAS_CARGA (ID, USR_ID, PLT_ID, RMT_ID, CAT_ID, CIU_ORG_ID, CIU_DST_ID, VHT_ID, UNI_ID, FECHA_DESDE, FECHA_HASTA, FECHA_PUBLICACION, DETALLE_CARGA, ELIMINADO, NUMERO_VIAJES, PRECIO_REFERENCIAL, ESPECIFICACION_ENTREGA, MOT_ID, CANTIDAD, MERCADERIA, FECHA_CADUCIDAD) VALUES (MST_OFC_SEQ.NextVal, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
	private static final String sqlDeleteByPK = "UPDATE MASTRANSPORTE.MST_OFERTAS_CARGA SET ELIMINADO='S'  WHERE ID = ?";
	private static final String sqlSelectByFiltroCarga = "SELECT oc.ID, oc.USR_ID, oc.PLT_ID, oc.RMT_ID, oc.CAT_ID, oc.CIU_ORG_ID, oc.CIU_DST_ID, oc.VHT_ID, oc.UNI_ID, oc.FECHA_DESDE, oc.FECHA_HASTA, oc.FECHA_PUBLICACION, oc.DETALLE_CARGA, oc.ELIMINADO, oc.NUMERO_VIAJES, oc.PRECIO_REFERENCIAL, oc.ESPECIFICACION_ENTREGA, oc.MOT_ID, oc.CANTIDAD, oc.MERCADERIA, oc.FECHA_CADUCIDAD FROM MASTRANSPORTE.MST_OFERTAS_CARGA oc, MASTRANSPORTE.VISTA_LOCALIDADES loco, MASTRANSPORTE.VISTA_LOCALIDADES_DESTINO locd where ";
	private static final String sqlUpdate = "UPDATE MASTRANSPORTE.MST_OFERTAS_CARGA SET USR_ID=?, PLT_ID=?, RMT_ID=?, CAT_ID=?, CIU_ORG_ID=?, CIU_DST_ID=?, VHT_ID=?, UNI_ID=?, FECHA_DESDE=?, FECHA_HASTA=?, FECHA_PUBLICACION=?, DETALLE_CARGA=?, ELIMINADO=?, NUMERO_VIAJES=?, PRECIO_REFERENCIAL=?, ESPECIFICACION_ENTREGA=?, MOT_ID=?, CANTIDAD=?, MERCADERIA=?, FECHA_CADUCIDAD=? where ID=?";

	private static final String sqlCountVigentes = "SELECT count(ID) cantidad FROM MASTRANSPORTE.MST_OFERTAS_CARGA where  ELIMINADO='N' and fecha_caducidad>=current_date";

	private DTOOfertaCarga setDatosRegistro(ResultSet rs) throws SQLException {
		DTOOfertaCarga dto = new DTOOfertaCarga();
		dto.setId(formatInteger(rs.getObject("ID")));
		dto.setIdUsuario(formatInteger(rs.getObject("USR_ID")));
		dto.setIdTipoPlataforma(formatInteger(rs.getObject("PLT_ID")));
		dto.setIdTipoRemolque(formatInteger(rs.getObject("RMT_ID")));
		dto.setIdTipoCarga(formatInteger(rs.getObject("CAT_ID")));
		dto.setIdCiudadOrigen(formatInteger(rs.getObject("CIU_ORG_ID")));
		dto.setIdCiudadDestino(formatInteger(rs.getObject("CIU_DST_ID")));
		dto.setIdTipoVehiculo(formatInteger(rs.getObject("VHT_ID")));
		dto.setIdTipoUnidad(formatInteger(rs.getObject("UNI_ID")));
		dto.setFechaDesde(formatDate(rs.getDate("FECHA_DESDE")));
		dto.setFechaHasta(formatDate(rs.getDate("FECHA_HASTA")));
		dto.setFechaPublicacion(formatDate(rs.getDate("FECHA_PUBLICACION")));
		dto.setDetalleCarga(formatString(rs.getObject("DETALLE_CARGA")));
		dto.setEliminado(formatString(rs.getObject("ELIMINADO")));
		dto.setNumeroViajes(formatInteger(rs.getObject("NUMERO_VIAJES")));
		dto.setPrecioReferencial(formatInteger(rs.getObject("PRECIO_REFERENCIAL")));
		dto.setEspecificacionEntrega(formatString(rs.getObject("ESPECIFICACION_ENTREGA")));
		dto.setIdTipoMoneda(formatInteger(rs.getObject("MOT_ID")));
		dto.setCantidad(formatInteger(rs.getObject("CANTIDAD")));
		dto.setMercaderia(formatString(rs.getObject("MERCADERIA")));
		dto.setFechaCaducidad(formatDate(rs.getDate("FECHA_CADUCIDAD")));
		return dto;
	}

	public Integer generateId() {
		Parametro[] params = null;
		Integer id = null;
		try {
			getConnection();
			ResultSet rs = executeQuery(sqlGetId, params);
			while (rs.next()) {
				id = formatInteger(rs.getObject("IDX"));
			}

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			closeConnection();
		}
		return id;
	}

	//

	/**
	 * metodo para listar las ofertas vigentes o historicas
	 * 
	 * @param id
	 * @return
	 */

	public Collection findByFiltroCarga(FiltroCargaDTO filtro) {

		log.debug("busco ofertas de tipo["+filtro.getTipoFiltro()+"] del user["+filtro.getIdUser()+"]");
		Collection col = new LinkedList();
		DTOOfertaCarga dto = new DTOOfertaCarga();
		String where = armaWhere(filtro);
		log.debug("busco por filtro:"+sqlSelectByFiltroCarga+where);
		Parametro[] params = null;
		try {
			getConnection();
			ResultSet rs;
			rs = executeQuery(sqlSelectByFiltroCarga+where, params);
			while (rs.next()) {
				 dto = setDatosRegistro( rs );
				col.add( dto );
			}

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			closeConnection();
		}

		return col;
	}

	public DTOOfertaCarga findByPrimaryKey(Integer id) {

		DTOOfertaCarga dto = new DTOOfertaCarga();
		Parametro[] params = new Parametro[] { getParametro(id, Types.INTEGER) };
		try {
			getConnection();

			ResultSet rs = executeQuery(sqlFindByPK, params);
			while (rs.next()) {
				dto = setDatosRegistro(rs);
			}

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			closeConnection();
		}

		return dto;
	}

	public Collection<DTOOfertaCarga> findAll() {

		Parametro[] params = null;
		Collection<DTOOfertaCarga> col = new LinkedList<DTOOfertaCarga>();
		try {
			getConnection();

			ResultSet rs = executeQuery(sqlFindAll, params);
			while (rs.next()) {
				DTOOfertaCarga dto = setDatosRegistro(rs);
				col.add(dto);
			}

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			closeConnection();
		}

		return col;
	}

	public String countOfertaCargaVigente() {

		Parametro[] params = null;
		String cant = "1656";
		try {
			getConnection();

			ResultSet rs = executeQuery(sqlCountVigentes, params);
			while (rs.next()) {
				cant = rs.getString("cantidad");

			}

		} catch (Exception e) {
			log.error("error al contar las ofertas vigentes:" + e.getMessage());
			log.error(e);
		} finally {
			closeConnection();
		}

		return cant;
	}

	public int deleteByPrimaryKey(Long id) {

		Parametro[] params = new Parametro[] { getParametro(id, Types.INTEGER) };
		int res = -1;
		try {
			getConnection();
			res = executeUpdate(sqlDeleteByPK, params);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			closeConnection();
		}

		return res;
	}

	public int create(DTOOfertaCarga dto) {

		Parametro[] params = new Parametro[] {
			getParametro(dto.getIdUsuario(), Types.INTEGER),
			getParametro(dto.getIdTipoPlataforma(), Types.INTEGER),
			getParametro(dto.getIdTipoRemolque(), Types.INTEGER),
			getParametro(dto.getIdTipoCarga(), Types.INTEGER),
			getParametro(dto.getIdCiudadOrigen(), Types.INTEGER),
			getParametro(dto.getIdCiudadDestino(), Types.INTEGER),
			getParametro(dto.getIdTipoVehiculo(), Types.INTEGER),
			getParametro(dto.getIdTipoUnidad(), Types.INTEGER),
			getParametro(formatTimestamp(dto.getFechaDesde()), Types.TIMESTAMP),
			getParametro(formatTimestamp(dto.getFechaHasta()), Types.TIMESTAMP),
			getParametro(formatTimestamp(dto.getFechaPublicacion()), Types.TIMESTAMP),
			getParametro(dto.getDetalleCarga(), Types.VARCHAR),
			getParametro(dto.getEliminado(), Types.VARCHAR),
			getParametro(dto.getNumeroViajes(), Types.INTEGER),
			getParametro(dto.getPrecioReferencial(), Types.INTEGER),
			getParametro(dto.getEspecificacionEntrega(), Types.VARCHAR),
			getParametro(dto.getIdTipoMoneda(), Types.INTEGER),
			getParametro(dto.getCantidad(), Types.INTEGER),
			getParametro(dto.getMercaderia(), Types.VARCHAR),
			getParametro(formatTimestamp(dto.getFechaCaducidad()), Types.TIMESTAMP)
		};

		int res = -1;
		try {
			getConnection();
			res = executeUpdate(sqlCreate, params);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			closeConnection();
		}

		return res;
	}

	public int update(DTOOfertaCarga dto) {

		Parametro[] params = new Parametro[] {
			getParametro(dto.getIdUsuario(), Types.INTEGER),
			getParametro(dto.getIdTipoPlataforma(), Types.INTEGER),
			getParametro(dto.getIdTipoRemolque(), Types.INTEGER),
			getParametro(dto.getIdTipoCarga(), Types.INTEGER),
			getParametro(dto.getIdCiudadOrigen(), Types.INTEGER),
			getParametro(dto.getIdCiudadDestino(), Types.INTEGER),
			getParametro(dto.getIdTipoVehiculo(), Types.INTEGER),
			getParametro(dto.getIdTipoUnidad(), Types.INTEGER),
			getParametro(formatTimestamp(dto.getFechaDesde()), Types.TIMESTAMP),
			getParametro(formatTimestamp(dto.getFechaHasta()), Types.TIMESTAMP),
			getParametro(formatTimestamp(dto.getFechaPublicacion()), Types.TIMESTAMP),
			getParametro(dto.getDetalleCarga(), Types.VARCHAR),
			getParametro(dto.getEliminado(), Types.VARCHAR),
			getParametro(dto.getNumeroViajes(), Types.INTEGER),
			getParametro(dto.getPrecioReferencial(), Types.INTEGER),
			getParametro(dto.getEspecificacionEntrega(), Types.VARCHAR),
			getParametro(dto.getIdTipoMoneda(), Types.INTEGER),
			getParametro(dto.getCantidad(), Types.INTEGER),
			getParametro(dto.getMercaderia(), Types.VARCHAR),
			getParametro(formatTimestamp(dto.getFechaCaducidad()), Types.TIMESTAMP),
			getParametro(dto.getId(), Types.INTEGER)
		};

		int res = -1;
		try {
			getConnection();
			res = executeUpdate(sqlUpdate, params);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			closeConnection();
		}

		return res;
	}

	private String  armaWhere(FiltroCargaDTO filtro){
		StringBuffer where= new StringBuffer(); 
		/**
		 *[fechaDesde=, 
		 *fechaHasta=, 
		 *paisOrigen=, 
		 *regionOrigen=, 
		 *ciudadOrigen=null, 
		 *paisDestino=, 
		 *regionDestino=, 
		 *ciudadDestino=null, 
		 *tipoFiltro=actual]
		 */
	
		
		where.append("oc.CIU_ORG_ID= loco.CIUDAD_ID and "); 
		where.append("oc.CIU_DST_ID= locd.CIUDAD_ID and ");
		where.append("oc.USR_ID="+filtro.getIdUser()+" and ");

		if (filtro.getTipoFiltro().equals("Vigente"))
			where.append("(oc.eliminado='N' and oc.fecha_caducidad>=SYSDATE) and ");
		else 
			where.append("(oc.eliminado='S' or oc.fecha_caducidad<SYSDATE) and ");
		
		if(filtro.getFechaDesde()==null || filtro.getPaisOrigen()==null){
			where.append(" 1=1"); 
			return where.toString();
		}
		
		
		if(filtro.getFechaDesde().length()>0 && filtro.getFechaHasta().length()>0)
			where.append(" oc.FECHA_CADUCIDAD between to_date ('"+filtro.getFechaDesde()+"', 'dd/mm/yyyy') AND to_date ('"+filtro.getFechaHasta()+"' , 'dd/mm/yyyy') and ");  
	
		if((filtro.getRegionOrigen()!=null && !filtro.getRegionOrigen().equals("16"))) 
			where.append("loco.REGION_ID="+filtro.getRegionOrigen()+" and"); 
		
		if ((filtro.getRegionDestino()!=null && !filtro.getRegionDestino().equals("16"))) 
			where.append("locd.REGION_ID="+filtro.getRegionDestino()+" and "); 
		
		
		
		if((filtro.getRegionOrigen()!=null && !filtro.getRegionOrigen().equals("16"))) 
			where.append("loco.PAIS_ID="+filtro.getPaisOrigen()+" and"); 
		
		if ((filtro.getRegionDestino()!=null && !filtro.getRegionDestino().equals("16"))) 
			where.append("locd.PAIS_ID="+filtro.getPaisDestino()+" and "); 		

		
		where.append(" 1=1"); 
		
		return where.toString();
	}
	
	
	public Collection<DTOOfertaCarga> findByFiltro(FiltroTransportistaDTO filtro) {
		int ind = 0;
		if (filtro.getFechaDesde() != null)
			ind++;
		if (filtro.getFechaHasta() != null)
			ind++;
		if (filtro.getIdPaisOrigen() != null)
			ind++;
		if (filtro.getIdRegionOrigen() != null)
			ind++;
		if (filtro.getIdPaisDestino() != null)
			ind++;
		if (filtro.getIdRegionDestino() != null)
			ind++;

		Parametro[] params = new Parametro[ind];

		String sqlFinal = sqlFindSinWhere + " where";
		String and = "";

		ind = 0;
		if ("H".equals(filtro.getTipoFiltro())) {
			sqlFinal += and + " FECHA_HASTA<=CURRENT_DATE AND ELIMINADO<>'N'";
			and = " AND";
		} else {
			sqlFinal += and + " FECHA_HASTA>CURRENT_DATE AND ELIMINADO='N'";
			and = " AND";
		}
		if (filtro.getFechaDesde() != null) {
			sqlFinal += and + " FECHA_DESDE=?";
			params[ind++] = getParametro(filtro.getFechaDesde(), Types.DATE);
			and = " AND";
		}
		if (filtro.getFechaHasta() != null) {
			sqlFinal += and + " FECHA_HASTA=?";
			params[ind++] = getParametro(filtro.getFechaDesde(), Types.DATE);
			and = " AND";
		}
		if (filtro.getIdPaisOrigen() != null) {
			sqlFinal += and + " PAI_ORG_ID=?";
			params[ind++] = getParametro(filtro.getIdPaisOrigen(), Types.INTEGER);
			and = " AND";
		}
		if (filtro.getIdRegionOrigen() != null) {
			sqlFinal += and + " RGN_ORG_ID=?";
			params[ind++] = getParametro(filtro.getIdRegionOrigen(), Types.INTEGER);
			and = " AND";
		}
		if (filtro.getIdPaisDestino() != null) {
			sqlFinal += and + " PAI_DST_ID=?";
			params[ind++] = getParametro(filtro.getIdPaisDestino(), Types.INTEGER);
			and = " AND";
		}
		if (filtro.getIdRegionDestino() != null) {
			sqlFinal += and + " RGN_DST_ID=?";
			params[ind++] = getParametro(filtro.getIdRegionDestino(), Types.INTEGER);
			and = " AND";
		}

		Collection<DTOOfertaCarga> col = new LinkedList<DTOOfertaCarga>();
		try {
			getConnection();

			ResultSet rs = executeQuery(sqlFinal, params);
			while (rs.next()) {
				DTOOfertaCarga dto = setDatosRegistro(rs);
				col.add(dto);
			}

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			closeConnection();
		}

		return col;
	}

}
